package me.stone.stanimeclient.page.home

import android.os.Bundle
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.util.getOrElse
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayoutMediator
import com.youth.banner.indicator.RectangleIndicator
import com.youth.banner.listener.OnBannerListener
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import me.stone.stanimeclient.MainViewModel
import me.stone.stanimeclient.base.AbsViewBindingFragment
import me.stone.stanimeclient.core.common.extensions.launchAndRepeatWithLifecycle
import me.stone.stanimeclient.core.model.FanSimpleItem
import me.stone.stanimeclient.databinding.FragmentHomeBinding
import me.stone.stanimeclient.util.autoCleared
import timber.log.Timber

@AndroidEntryPoint
class HomeFragment : AbsViewBindingFragment<FragmentHomeBinding>(),
    OnBannerListener<FanSimpleItem> {

    private var updateAdapter: Adapter by autoCleared()

    private val mainViewModel: MainViewModel by activityViewModels()

    private val viewModel: HomeViewModel by activityViewModels()

    private val bannerAdapter by lazy { ImageTitleBannerAdapter() }

    override fun buildViewBinding(
        inflater: LayoutInflater,
        container: ViewGroup?
    ): FragmentHomeBinding {
        return FragmentHomeBinding.inflate(inflater, container, false).apply {
            viewModel = this@HomeFragment.viewModel
            executePendingBindings()
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setupBanner()
        setupTabPagerUI()

        launchAndRepeatWithLifecycle {
            launch {
                viewModel.bannerData.collect {
                    bannerAdapter.setDatas(it)
                }
            }

            launch {
                viewModel.errorMessage.collect {
                    Timber.e(it)
                    Toast.makeText(context, it, Toast.LENGTH_SHORT).show()
                }
            }

            launch {
                viewModel.recommendQuery.collectLatest {
                    mainViewModel.updateRecommendQuery(it)
                }
            }

            launch {
                viewModel.navigationId.collectLatest {
                    findNavController().navigate(it)
                }
            }

        }

    }

    /********************************************
     * home banner page
     */

    private fun setupBanner() {
        binding.banner
            .addBannerLifecycleObserver(viewLifecycleOwner)
            .setIndicator(RectangleIndicator(context))
            .setAdapter(bannerAdapter)
            .setOnBannerListener(this)
            .setLoopTime(3000)
    }

    override fun OnBannerClick(data: FanSimpleItem?, position: Int) {
        data?.let { mainViewModel.seeFanDetailItem(it.id) }
    }


    /********************************************
     * weekday update page
     */

    private fun setupTabPagerUI() = binding.apply {
        updateAdapter = Adapter(this@HomeFragment)
        pages.adapter = updateAdapter
        TabLayoutMediator(tabs, pages) { tab, position ->
            tab.text = updateAdapter.getFragmentName(position)
        }.attach()
    }

    private inner class Adapter (
        fragment: Fragment,
        private val fragments: SparseArray<HomeUpdateFragment> = SparseArray()
    ): FragmentStateAdapter(fragment) {

        private val weekdays = arrayOf(
            "日", "一", "二", "三", "四", "五", "六"
        )

        override fun getItemCount(): Int {
            return weekdays.size
        }

        override fun createFragment(position: Int): Fragment {
            val fragment = fragments.getOrElse(position) {
                HomeUpdateFragment().apply {
                    setWeekday(position)
                }
            }
            fragments.put(position, fragment)
            return fragment
        }

        fun getFragmentName(position: Int) = weekdays[position]

    }
}